// 命令式编程：原生js开发或者jquery通过命令操作DOM对象完成数据更改，界面优化。
// 声明式编程：框架底层已将封装号模块帮助我们来完成DOM的操作，只需去声明即可使用 vue react angular {{}}
// 编程范式：命令式编程和声明式编程
// 编程范式：面向对象的编程与面向过程的编程
// 面向过程方式 他的第一个公民是函数，他围绕着函数进行编程，也是函数式编程

const nums = [10,20,111,222,444,40,50]

// 1.从nums数组中取出小于100的数
let newNums = []
for (const n of nums) {
    if (n < 100) {
        newNums.push(n)
    }
}
console.log(newNums);

// 2.从1要求中小于100的数都×2
let newNewNums = []
for (const n of newNums) {
    if (n < 100) {
        newNums.push(n*2)
    }
}
console.log(newNewNums);

// 3.从2要求中，把所有的数进行累加
let total = 0
for (const n of newNewNums) {
    total += n
}
console.log(total);


// 函数式编程
// 封装了一些函数用来实现一些效果
// filter函数的使用
// 参数是一个回调函数，数组有多少成员，就回调多少次
let newNums1 = nums.filter(function (n) {   // 回调函数编写过滤规则
    // 匿名函数，有一个参数n，每次回调数组成员，第一个n是10，第二次回调20，以此类推
    // 匿名函数被要求必须返回一个值，return，是布尔值，true 返回n进入到新的数组，如果是false，则不返回
    return n < 100
})
console.log(newNums1);


// 2 map函数的使用
// 它可以对数组中每个内容进行一些操作
// 参数也可为一个匿名的回调函数
let newNewNums1 = newNums1.map(function (n) {
    return n * 2
})
console.log(newNewNums1);   

// 3 reduce函数的使用,第一个参数为回调函数，第二个参数为默认值
// 作用就是对数组所有内容进行一个汇总
let total1 = newNewNums1.reduce(function (preValue, n) {
    // 匿名函数有两个参数，第一个参数preValue是上一次回调的返回值，第一次回调时，preValue为默认值0
    // 第二个参数n是当前回调的数组成员
    return preValue + n
})
console.log(total1);


// 函数式编程
//把3个需求进行综合，一起推出
let totalnums = nums.filter(function (n) {
    return n < 100
}).map(function (n) {
    return n * 2
}).reduce(function (pre, n) {
    return pre + n
},0)
console.log(totalnums);

// 箭头函数
let totalnums2 = nums.filter(n => n < 100).map(n => n * 2).reduce((pre, n) => pre + n, 0)
console.log(totalnums2);